/*****************************************************************************
* @author  : windsPx                                                         *
* @date    :                                                                 *
* @file    :                                                                 *
* @brief   :                                                                 *
*----------------------------------------------------------------------------*
* Date        | Version   | Author         | Description                     *
*----------------------------------------------------------------------------*
*             |           |  windsPx              |  ringbuf只是在接近单线程 业务处理慢一样会造成阻塞
*****************************************************************************/

#pragma once

#include <vector>
#include <memory>
#include "CommonDef.h"
#include "RiBaseObj.h"
#include <type_traits>

namespace _disruptor
{
/*
template <int Type>
class CRingOrderNum;

//! 单生产者 当前最大序号
template<>
class CRingOrderNum<ProduceType_Single>
{
protected:
	volatile RINGINDEX m_max_order_num = 0;
public:
	CRingOrderNum() : m_max_order_num(0)
	{
	}
};

//! 多生产者 当前最大序号
template<>
class CRingOrderNum<ProduceType_Multi>
{
protected:
	std::atomic<RINGINDEX> m_max_order_num;
public:
	CRingOrderNum() : m_max_order_num(0)
	{
	}
};
*/

template <int Type>
class CRingOrderNum
{
protected:
    std::atomic<RINGINDEX> m_max_order_num;
public:
    CRingOrderNum() : m_max_order_num(0)
    {
    }
};

//E必须提供WriteData(const char* data, int length)接口
//buf_size是申请ringbuf的大小
template <typename E, int ProduceType = ProduceType_Multi, int buf_size = BuffLen, typename Alloc = std::allocator<E> >
class CRingBuffer : public CRingOrderNum<ProduceType>
{
public:
	using BUFEntry = E;
private:
	//! ringbuf的物理空间
	std::vector<E, Alloc > m_buf;
	//! ring的长度 -- 2^n
	const int m_buf_size = buf_size;
public:
	CRingBuffer()
		: CRingOrderNum<ProduceType>()
	{
		m_buf.resize(m_buf_size);
	}
    ~CRingBuffer()
    {
    }
public:
	int RingBuffSize()
	{
		return m_buf_size;
	}
	//当前最大序号
	RINGINDEX MaxOrderNum()
	{
		return CRingOrderNum<ProduceType>::m_max_order_num.load(std::memory_order_relaxed);
	}
	//当前最小序号
	RINGINDEX MinOrderNum()
	{
		int min_order = 0;
		min_order = CRingOrderNum<ProduceType>::m_max_order_num.load(std::memory_order_relaxed) - m_buf_size + 1;
		return min_order < 0 ? 0 : min_order;
	}
	//序号转成vector的index
	int Index(RINGINDEX order_num)
	{
		return order_num & ((int)m_buf.size() - 1);
	}
	//获取对应序号的缓存对象
	E* GetEntry(RINGINDEX order_num)
	{
		return &m_buf[Index(order_num)];
	}
	//向指定序号的缓存对象写入数据
	bool WriteEntry(RINGINDEX order_num, const char* data, int length)
	{
		E* pEntry = GetEntry(order_num);
		pEntry->WriteData(data, length);
		return true;
	}
	bool WriteEntry(RINGINDEX order_num, void* obj_ptr, int customer_num)
	{
		E* pEntry = GetEntry(order_num);
		pEntry->SetInnerObj(obj_ptr, customer_num);
		return true;
	}
	//写入提交后 max_order_num要变更
	void Commit(RINGINDEX order_num)
	{
		CRingOrderNum<ProduceType>::m_max_order_num.store(order_num, std::memory_order_release);
	}

#ifdef BUF_TRANS
    char* getWriteBuff(RINGINDEX order_num)
    {
        return m_buf[Index(order_num)].bufPos();
    }
#endif
};
}
